package com.sl.repositry.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import com.sl.entity.dto.OrganDTO;
import com.sl.entity.dto.TransportLineNodeDTO;
import com.sl.entity.node.AgencyEntity;
import com.sl.enums.OrganTypeEnum;
import com.sl.repositry.TransportLineRepository;
import org.neo4j.driver.Value;
import org.neo4j.driver.internal.value.PathValue;
import org.neo4j.driver.types.Path;
import org.springframework.data.neo4j.core.Neo4jClient;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Optional;

@Repository
public class TransportLineRepositoryImpl implements TransportLineRepository {

    @Resource
    Neo4jClient neo4jClient;


    @Override
    public TransportLineNodeDTO findShortestPath(AgencyEntity start, AgencyEntity end) {
        // //查询两个网点之间最短路径，查询深度最大为10
        String cypherStr = "MATCH path = shortestPath((n:AGENCY) -[*..10]->(m:AGENCY))\n" +
                "        WHERE n.bid = $startId AND m.bid = $endId " +
                "        RETURN path";

        Optional<TransportLineNodeDTO> optional = neo4jClient.query(cypherStr)
                .bind(start.getBid()).to("startId")
                .bind(end.getBid()).to("endId")
                .fetchAs(TransportLineNodeDTO.class)
                .mappedBy(((typeSystem, record) -> {
                    TransportLineNodeDTO dto = new TransportLineNodeDTO();
                    // TODO  将结果解析到dto对象
                    PathValue pathValue = (PathValue)record.get(0);
                    Path path = pathValue.asPath();
                    path.nodes().forEach(node -> {
                         // 将 node节点 -->  OrganDTO对象
                        Map<String, Object> map = node.asMap();
                        OrganDTO organDTO = BeanUtil.toBeanIgnoreError(map, OrganDTO.class);

                        // 网点类型的处理 Agency            TLT
                        String first = CollUtil.getFirst(node.labels());
                        organDTO.setType(OrganTypeEnum.valueOf(first).getCode());
                        // 处理经纬度
                        Object location = map.get("location"); //  x 经度     y 纬度
                        organDTO.setLongitude(BeanUtil.getProperty(location, "x"));
                        organDTO.setLatitude(BeanUtil.getProperty(location, "y"));
                        // 将organDto对象，加入到TransportLineNodeDTO的集合属性中
                        dto.getNodeList().add(organDTO);
                    });

                    path.relationships().forEach(relationship -> {
                        Map<String, Object> map = relationship.asMap();
                        // cost
                        Double cost = MapUtil.getDouble(map, "cost");
                        dto.setCost(dto.getCost() + cost);
                    });

                    return dto;
                })).one();
        return optional.get();
    }


}
